#ifndef __PANEL_REVERB_H__
#define __PANEL_REVERB_H__

#include <wx/wx.h>
#include <wx/aui/aui.h>
#include <wx/wrapsizer.h>
#include <wx/event.h>
#include <wx/xml/xml.h>
#include "MyCommon.h"

class MyEventReverb : public wxCommandEvent {
public:
    MyEventReverb(wxEventType eventType = wxEVT_NULL,int id = 0)
        : wxCommandEvent(eventType, id) {

        }

    // 克隆事件对象
//    [[nodiscard]] // C++17 才支持，意思就是函数返回值不能被忽略，否则编译器发出警告
    virtual wxEvent *Clone() const override {
        return new MyEventReverb(*this);
    }

    void SetDry(double dry) {
        m_dry = dry;
    }
    void SetWet(double wet) {
        m_wet = wet;
    }
    void SetDamping(double damping) {
        m_damping = damping;
    }
    void SetTone(double tone) {
        m_tone = tone;
    }
    void SetFeedback(double feedback) {
        m_feedback = feedback;
    }
    void SetEnable(bool enable) {
        this->enable = enable;
    }
    double GetDry() {
        return m_dry;
    }
    double GetWet() {
        return m_wet;
    }
    double GetDamping() {
        return m_damping;
    }
    double GetTone() {
        return m_tone;
    }
    double GetFeedback() {
        return m_feedback;
    }
    bool GetEnable() {
        return enable;
    }
    void SetPresetIndex(const unsigned int index) {
        preset_index = index;
    }
    int GetPresetIndex() {
        return preset_index;
    }

private:

    double m_dry;
    double m_wet;
    double m_damping;
    double m_tone;
    double m_feedback;
    bool enable;
    int preset_index;

};

wxDECLARE_EVENT(myEVT_REVERB, MyEventReverb);
wxDECLARE_EVENT(myEVT_REVERB_DRY, MyEventReverb);
wxDECLARE_EVENT(myEVT_REVERB_WET, MyEventReverb);
wxDECLARE_EVENT(myEVT_REVERB_DAMPING, MyEventReverb);
wxDECLARE_EVENT(myEVT_REVERB_TONE, MyEventReverb);
wxDECLARE_EVENT(myEVT_REVERB_FEEDBACK, MyEventReverb);
wxDECLARE_EVENT(myEVT_REVERB_ENABLE, MyEventReverb);

typedef void (wxEvtHandler::*MyReverbEventFunction)(MyEventReverb &);

#define MyReverbEventHandler(func) \
    wxEVENT_HANDLER_CAST(MyReverbEventFunction, func)

#define M_EVT_REVERB(id, fn) \
    wx__DECLARE_EVT1(myEVT_REVERB, id, MyReverbEventHandler(fn))
#define M_EVT_REVERB_DRY(id, fn) \
    wx__DECLARE_EVT1(myEVT_REVERB_DRY, id, MyReverbEventHandler(fn))
#define M_EVT_REVERB_WET(id, fn) \
    wx__DECLARE_EVT1(myEVT_REVERB_WET, id, MyReverbEventHandler(fn))
#define M_EVT_REVERB_DAMPING(id, fn) \
    wx__DECLARE_EVT1(myEVT_REVERB_DAMPING, id, MyReverbEventHandler(fn))
#define M_EVT_REVERB_TONE(id, fn) \
    wx__DECLARE_EVT1(myEVT_REVERB_TONE, id, MyReverbEventHandler(fn))
#define M_EVT_REVERB_FEEDBACK(id, fn) \
    wx__DECLARE_EVT1(myEVT_REVERB_FEEDBACK, id, MyReverbEventHandler(fn))
#define M_EVT_REVERB_ENABLE(id, fn) \
    wx__DECLARE_EVT1(myEVT_REVERB_ENABLE, id, MyReverbEventHandler(fn))



class PanelReverb : public wxPanel
{
public:
    PanelReverb(const wxString &title, wxXmlNode *node, wxWindowID id = wxID_ANY, wxWindow *parent = nullptr);

    typedef struct
    {
        bool enable;
        float dry;
        float wet;
        float tone;
        float damp;
        float feedback;
    }param_struct;

private:

    // enum{
    //     ID_TXT_DRY = ID_START_PANEL_REVERB + 1,
    //     ID_TXT_WET,
    //     ID_TXT_FEEDBACK,
    //     ID_TXT_TONE,
    //     ID_TXT_DAMPING,
    //     ID_SLI_DRY,
    //     ID_SLI_WET,
    //     ID_SLI_FEEDBACK,
    //     ID_SLI_TONE,
    //     ID_SLI_DAMPING,
    //     ID_CHK_SWITCH,
    // };

    enum{
        EV_DRY=1,
        EV_WET,
        EV_FEEDBACK,
        EV_TONE,
        EV_DAMPING,
        EV_ENABLE,
    };

    const double dry_max = 6;
    const double dry_min = -30;
    const double dry_step = 0.1;
    const double wet_max = 6;
    const double wet_min = -30;
    const double wet_step = 0.1;
    const double feedback_max = 1;
    const double feedback_min = 0;
    const double feedback_step = 0.01;
    const double tone_max = 1;
    const double tone_min = 0;
    const double tone_step = 0.01;
    const double damp_max = 0.9;
    const double damp_min = 0.2;
    const double damp_step = 0.01;

    const char *attr_name_select = "select";
    const char *attr_name_preset_default = "default";
    const char *attr_name_param_enable = "enable";
    const char *attr_name_param_dry = "dry";
    const char *attr_name_param_wet = "wet";
    const char *attr_name_param_damp = "damp";
    const char *attr_name_param_tone = "tone";
    const char *attr_name_param_feedback = "feedback";

    wxWindowID ID_TXT_DRY;
    wxWindowID ID_TXT_WET;
    wxWindowID ID_TXT_FEEDBACK;
    wxWindowID ID_TXT_TONE;
    wxWindowID ID_TXT_DAMPING;
    wxWindowID ID_SLI_DRY;
    wxWindowID ID_SLI_WET;
    wxWindowID ID_SLI_FEEDBACK;
    wxWindowID ID_SLI_TONE;
    wxWindowID ID_SLI_DAMPING;
    wxWindowID ID_CHK_SWITCH;
    wxWindowID ID_MENU_VIEW_REVERB;
    wxWindowID ID_CHO_PRESET;

    wxAuiPaneInfo paneInfo;
    MyEventReverb param_event;
    param_struct param;
    wxXmlNode *root_node;
    wxXmlNode *preset_node;
    int select_index;

public:

    wxAuiPaneInfo &GetPaneInfo();
    void AppendToMenu(wxMenu *menu,bool is_checkable);
    void SetShow(bool show);
    double SetParamDry(double value);
    double SetParamWet(double value);
    double SetParamFeedback(double value);
    double SetParamTone(double value);
    double SetParamDamping(double value);
    bool SetParamEnable(bool value);
    double GetParamDry();
    double GetParamWet();
    double GetParamFeedback();
    double GetParamTone();
    double GetParamDamping() ;
    bool GetParamEnable();
    void SetPresetIndex(const unsigned int index);
    int GetPresetIndex();
    void PresetListClear(void);
    void AddPresetList(const wxString &preset_name);
    wxXmlNode *SaveCurrentParamsToNewPreset(wxXmlNode *root, const wxString &new_preset_name,int &is_same);
    bool WriteToXML(wxXmlNode *node);

private:
    void OnSliderChange(wxCommandEvent& event);
    void OnTextEnter(wxCommandEvent& event);
    void OnChkChange(wxCommandEvent& event);
    void OnCombChange(wxCommandEvent& event);

    void TrigerEvent(int ev);

    wxXmlNode *SelectPreset(wxString name);

    // wxDECLARE_EVENT_TABLE();
};


#endif
